package com.zhixun.mobile.modules.jiujiudevice;

import java.io.BufferedReader;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.boxin.ims.modules.jiujiudevice.entity.JiuDevice;
import com.boxin.ims.modules.jiujiudevice.entity.JiuOrderLog;
import com.boxin.ims.modules.jiujiudevice.entity.JiuOrderRecord;
import com.boxin.ims.modules.jiujiudevice.entity.JiuUserAgree;
import com.boxin.ims.modules.jiujiudevice.service.JiuCashConfigService;
import com.boxin.ims.modules.jiujiudevice.service.JiuCashRecordService;
import com.boxin.ims.modules.jiujiudevice.service.JiuDeviceService;
import com.boxin.ims.modules.jiujiudevice.service.JiuOrderLogService;
import com.boxin.ims.modules.jiujiudevice.service.JiuOrderRecordService;
import com.boxin.ims.modules.jiujiudevice.service.JiuUserAgreeService;
import com.boxin.ims.modules.wechat.entity.JiuWechatMember;
import com.boxin.ims.modules.wechat.entity.WXPay;
import com.boxin.ims.modules.wechat.entity.WeChat;
import com.boxin.ims.modules.wechat.service.JiuWechatMemberService;
import com.boxin.ims.modules.wechat.service.MobileMessageRecorderService;
import com.boxin.ims.modules.wechat.service.WXPayService;
import com.boxin.ims.modules.wechat.service.WeChatService;
import com.boxin.ims.modules.wechat.utils.JsTicketUtils;
import com.boxin.ims.modules.wechat.utils.WechatCacheUtils;
import com.boxin.ims.modules.wechat.utils.WechatInterfaceUtils;
import com.boxin.ims.modules.wechat.utils.WechatUtils;
import com.boxin.ims.modules.wechat.utils.XMLUtils;
import com.phoenix.fly.util.StringUtils;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.utils.CacheUtils;
import com.thinkgem.jeesite.common.utils.JedisUtils;
import com.thinkgem.jeesite.common.utils.RequestUtil;
import com.wxpay.client.util.CommonUtil;
import com.wxpay.client.util.WxPayHelper;
import com.zhixun.mobile.modules.base.web.BaseController;
import com.zhixun.mobile.modules.jiujiudevice.common.JsonResult;
import com.zhixun.mobile.modules.jiujiudevice.common.ResultCode;

/**
 * 处理用户订单（使用）
 * 
 * @author dongchao
 *
 */
@Controller
@RequestMapping(value = Global.FRONT_PATH + "/jiujiudevice")
public class JiuJiuMemberOrderFrontController extends BaseController {

	
	
	private Logger log = LoggerFactory.getLogger(JiuJiuMemberOrderFrontController.class);

	public static final Long USER_ID = 2L;

	@Autowired
	private MobileMessageRecorderService mobileMessageRecorderService;
	@Autowired
	private JiuWechatMemberService jiuWechatMemberService;
	@Autowired
	private JiuOrderRecordService jiuOrderRecordService;
	@Autowired
	private JiuOrderLogService jiuOrderLogService;
	@Autowired
	private WXPayService wxPayService;
	@Autowired
	private WeChatService weChatService;
	/**
	 * 设备管理
	 */
	@Autowired
	private JiuDeviceService jiuDeviceService;
	/**
	 * 押金全局配置
	 */
	@Autowired
	private JiuCashConfigService jiuCashConfigService;
	/**
	 * 押金记录
	 */
	@Autowired
	private JiuCashRecordService jiuCashRecordService;

	@Autowired
	private JiuUserAgreeService jiuUserAgreeService;
	/**
	 * 订单列表页
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "myorder")
	public String myorder(HttpServletRequest request, HttpServletResponse response, Model model) {
		String openId = getOpenId("userinfo_openid", request);
		if (StringUtils.isEmpty(openId)) {
			// 拉取授权
			System.err.println("拉取了授权方法===》" + openId);
			String url = WechatUtils.getOAuthUrl("/jiujiudevice/jiaoyajin", USER_ID, request, response);
			return "redirect:" + url;
		}

		JiuWechatMember member = getMember(USER_ID, openId);
		if (member == null) {
			// 拉取授权
			System.err.println("拉取了授权方法===》" + openId);
			String url = WechatUtils.getOAuthUrl("/jiujiudevice/jiaoyajin", USER_ID, request, response);
			return "redirect:" + url;
		}

		if (StringUtils.isEmpty(member.getMobile())) {
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/login";
		}

		/*//如果用户有正在使用的设备， 则显示 使用信息页
		String useOrderNo = JedisUtils.get(JiuDevice.MEMBER_USE_DEVICE_CACHE_KEY+"_"+member.getId());
		if(StringUtils.isNotEmpty(useOrderNo)) {
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/usetime";	
		}
		*/
		
		JiuOrderRecord jiuOrderRecord = new JiuOrderRecord();
		jiuOrderRecord.setMemberOpenId(openId);
		Page<JiuOrderRecord> page = jiuOrderRecordService.find(new Page<JiuOrderRecord>(request, response),
				jiuOrderRecord);

		model.addAttribute("page", page);

		return "modules/jiujiudeviceFront/myorder";
	}

	/**
	 * 订单详情页
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "orderDetail")
	public String orderDetail(HttpServletRequest request, HttpServletResponse response, Model model) {
		String openId = getOpenId("userinfo_openid", request);
		if (StringUtils.isEmpty(openId)) {
			// 拉取授权
			System.err.println("拉取了授权方法===》" + openId);
			String url = WechatUtils.getOAuthUrl("/jiujiudevice/jiaoyajin", USER_ID, request, response);
			return "redirect:" + url;
		}

		JiuWechatMember member = getMember(USER_ID, openId);
		if (member == null) {
			// 拉取授权
			System.err.println("拉取了授权方法===》" + openId);
			String url = WechatUtils.getOAuthUrl("/jiujiudevice/jiaoyajin", USER_ID, request, response);
			return "redirect:" + url;
		}

		if (StringUtils.isEmpty(member.getMobile())) {
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/login";
		}
		
		String orderNo = RequestUtil.getString(request, "orderNo");
		JiuOrderRecord order = jiuOrderRecordService.getByOrderNo(orderNo);
		
		JiuOrderLog orderLog = jiuOrderLogService.findByOrderNo(orderNo);
		//添加设备的类型
		String deviceType =  (String)JedisUtils.getObject(JiuDevice.DEVICE_TYPE+order.getDeviceSn());
		model.addAttribute("deviceType",deviceType);
		model.addAttribute("order", order);
		model.addAttribute("member", member);
		model.addAttribute("orderLog", orderLog);
		return "modules/jiujiudeviceFront/orderDetail";
	}
	/**
	 * 支付页面
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "pay")
	public String pay(HttpServletRequest request, HttpServletResponse response, Model model) {
		String openId = getOpenId("userinfo_openid", request);
		if (StringUtils.isEmpty(openId)) {
			// 拉取授权
			System.err.println("拉取了授权方法===》" + openId);
			String url = WechatUtils.getOAuthUrl("/jiujiudevice/jiaoyajin", USER_ID, request, response);
			return "redirect:" + url;
		}

		JiuWechatMember member = getMember(USER_ID, openId);
		if (member == null) {
			// 拉取授权
			System.err.println("拉取了授权方法===》" + openId);
			String url = WechatUtils.getOAuthUrl("/jiujiudevice/jiaoyajin", USER_ID, request, response);
			return "redirect:" + url;
		}

		if (StringUtils.isEmpty(member.getMobile())) {
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/login";
		}

		/*//获取用户正在使用的设备
		//如果用户有正在使用的设备， 则显示 使用信息页
		String o = JedisUtils.get(JiuDevice.MEMBER_USE_DEVICE_CACHE_KEY+"_"+member.getId());
		if(StringUtils.isNotEmpty(o)) {
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/usetime";	
		}*/
		
		JiuOrderRecord order = null;
		String orderNo = RequestUtil.getString(request, "orderNo");
		if(StringUtils.isEmpty(orderNo)) {
			//获取用户为支付的订单信息
			List<JiuOrderRecord> orderList = jiuOrderRecordService.queryUnpaidOrderByMember(member.getId());
			order = orderList.get(0);
		}else {
			order = jiuOrderRecordService.getByOrderNo(orderNo);
		}
		
		if(order == null) {
			log.error("用户【{}】【{}】唤起支付页失败，没有发现需要支付的设备订单",member.getOpenId(),member.getNickname());
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/usercenter";
		}
		
		JiuOrderLog orderLog = jiuOrderLogService.findByOrderNo(order.getOrderNo());
		if(orderLog == null) {
			log.error("用户【{}】【{}】唤起支付页失败，没有发现需要支付的设备订单明细",member.getOpenId(),member.getNickname());
			return "redirect:" + Global.FRONT_PATH + "/jiujiudevice/usercenter";
		}
		createJsApi(order, request, model);
		
		String message = RequestUtil.getString(request, "message");
		if(StringUtils.isNotEmpty(message)) {
			try {
				model.addAttribute("message", new String(message.getBytes("ISO8859-1"),Charset.forName("UTF-8")));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		//添加用户协议查询
		JiuUserAgree jiuUserAgree = jiuUserAgreeService.get(1L);
		//添加设备的类型
		String deviceType =  (String)JedisUtils.getObject(JiuDevice.DEVICE_TYPE+order.getDeviceSn());
		model.addAttribute("deviceType",deviceType);
		model.addAttribute("order", order);
		model.addAttribute("orderLog", orderLog);
		model.addAttribute("member", member);
		model.addAttribute("jiuUserAgree",jiuUserAgree);
		return "modules/jiujiudeviceFront/pay";
	}
	
	
	/**
	 * 根据USERID获取weChat
	 * 
	 * @param request
	 * @param user
	 * @return
	 */
	public WeChat getWeChat(HttpServletRequest request, Long userId) {
		WeChat weChat = (WeChat) CacheUtils.get("we_chat_" + userId);
		if (weChat == null) {
			weChat = weChatService.getWeChatByUserId(userId);
			CacheUtils.put("we_chat_" + userId, weChat);
		}
		return weChat;
	}

	/**
	 * 生成访问微信支付jsapi 押金支付 微信下单
	 * 
	 * @param model
	 * @param rechargeOrder
	 * @param request
	 * @return
	 */
	private String createJsApi(JiuOrderRecord order, HttpServletRequest request, Model model) {
		String JSAPI = "";
		WXPay wxPay = wxPayService.getByUserId(USER_ID);
		if (wxPay == null) {
			request.setAttribute("message", "商户配置不正确！");
		} else {
			// 微信支付jsapi 生成json
			WeChat weChat = getWeChat(request, USER_ID);
			String nonce_str = CommonUtil.CreateNoncestr();
			String basePath = request.getScheme() + "://" + request.getServerName() + request.getContextPath();
			WxPayHelper wxPayHelper = new WxPayHelper();
			wxPayHelper.setApiKey(wxPay.getApiKey());
			wxPayHelper.setAppId(weChat.getAppId());
			wxPayHelper.setMchId(wxPay.getMchId());
			wxPayHelper.SetParameter("nonce_str", nonce_str);
			wxPayHelper.SetParameter("body", "设备支付");
			wxPayHelper.SetParameter("out_trade_no", order.getOrderNo());

/*			wxPayHelper.SetParameter("total_fee", String.format("%.0f", order.getAmount() * 100));
测试使用的，上线需要修改*/
			wxPayHelper.SetParameter("total_fee", String.format("%.0f",order.getAmount() * 100));
			wxPayHelper.SetParameter("spbill_create_ip", RequestUtil.getUserIpAddr(request));
			wxPayHelper.SetParameter("notify_url", basePath + "/f/jiujiudevice/wxNotify");
			wxPayHelper.SetParameter("trade_type", "JSAPI");
			wxPayHelper.SetParameter("openid", order.getMemberOpenId());
			try {
				JSAPI = wxPayHelper.createPayUrlByJSAPI();
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
			model.addAttribute("JSAPI", JSAPI);
			log.info("JSAPI:" + JSAPI);
		}
		return JSAPI;
	}

	/**
	 * 查询微信订单
	 * 
	 * @param order
	 * @param request
	 * @return
	 */
	private Map<String, String> findPayUrlByJSAPI(String orderNO, HttpServletRequest request) {
		WXPay wxPay = wxPayService.getByUserId(USER_ID);
		if (wxPay == null) {
			request.setAttribute("message", "商户配置不正确！");
		} else {
			// 微信支付jsapi 生成json
			WeChat weChat = getWeChat(request, USER_ID);
			WxPayHelper wxPayHelper = new WxPayHelper();
			wxPayHelper.setApiKey(wxPay.getApiKey());
			wxPayHelper.setAppId(weChat.getAppId());
			wxPayHelper.setMchId(wxPay.getMchId());
			wxPayHelper.SetParameter("nonce_str", CommonUtil.CreateNoncestr());
			wxPayHelper.SetParameter("out_trade_no", orderNO);

			try {
				return wxPayHelper.findPayUrlByJSAPI();
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}
	
	
	/**
	 * 
	 * @function:
	 *  <p>
	 *  wx.config({ debug: true, //
	 *  开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，
	 *  参数信息会通过log打出，仅在pc端时才会打印。 appId: '', // 必填，公众号的唯一标识 timestamp: , //
	 *  必填，生成签名的时间戳 nonceStr: '', // 必填，生成签名的随机串 signature: '',// 必填，签名
	 *  jsApiList: [] // 必填，需要使用的JS接口列表 });
	 *  </p>
	 * @param request
	 * @param userId
	 */
	public void getJsapiTicket(HttpServletRequest request, Long userId) {
		WeChat weChat = WechatCacheUtils.getWeChatByUserId(userId);
		// jsapi ticket 生成
		String ticket = JsTicketUtils.getJSAPITicket(weChat);
		// 获取路径
		String url = request.getRequestURL() + "";
		if (request.getQueryString() != null) {
			url += "?" + request.getQueryString();
		}
		Map<String, String> result = new HashMap<String, String>();
			result = WechatInterfaceUtils.sign(ticket, url);
			request.setAttribute("signature", result.get("signature"));
			request.setAttribute("nonceStr", result.get("nonceStr"));
			request.setAttribute("timestamp", result.get("timestamp"));
			request.setAttribute("weChatAppId", weChat.getAppId());
	}

	/**
	 * 微信支付回调
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "wxNotify")
	public String wxNotify(HttpServletRequest request, HttpServletResponse response, Model model)
			throws Exception {

		StringBuffer stringBuffer = new StringBuffer();
		BufferedReader bReader = request.getReader();
		String line = "";
		while ((line = bReader.readLine()) != null) {
			stringBuffer.append(line);
		}
		Map<String, String> xmlMap = XMLUtils.xml2Map(stringBuffer.toString());

		String resXml = null;

		if ("SUCCESS".equals(xmlMap.get("xml.result_code"))) {
			String orderNo = xmlMap.get("xml.out_trade_no");
			JiuOrderRecord order = jiuOrderRecordService.getByOrderNo(orderNo);
			
			if(!JiuOrderRecord.STATUS_NO_PAY.equals(order.getStatus())) {
				return "重复回调;";
			}
			
			// 验证
			Map<String, String> result = findPayUrlByJSAPI(order.getOrderNo(), request);

			if (!"SUCCESS".equals(result.get("return_code"))) {
				log.error("订单-【" + orderNo + "】支付失败,调用查询接口失败,网络不通");
				return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>";
			}

			if (!"SUCCESS".equals(result.get("result_code"))) {
				log.error("订单-【" + orderNo + "】支付失败,调用查询接口失败，err_code=" + result.get("err_code") + "|" + "err_code_des="
						+ result.get("err_code_des"));
				return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>";
			}
			// 验证交易状态
			String trade_state = result.get("trade_state");
			if (!"SUCCESS".equals(trade_state)) {
				// 交易失败
				log.error("订单-【" + orderNo + "】支付失败 trade_state=" + trade_state);
				resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>";
			}

			// 支付成功后 验证 支付金额
			String total_fee = result.get("total_fee");
           //	测试使用的，上线需要修改		
			if (total_fee.equals(String.format("%.0f",  order.getAmount()* 100))) {
				// 支付金额 正确
				// 处理业务逻辑
				order.setStatus(1);
				order.setPayTime(new Date());
				jiuOrderRecordService.save(order);
			} else {
				resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>";
				log.error("订单-【" + orderNo + "】支付成功 支付金额错误;应付金额【" + String.format("%.0f", order.getAmount() * 100)
						+ "】实付金额【" + total_fee + "】");
			}

			resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
		} else {
			resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[支付失败]]></return_msg></xml>";
		}
		return resXml;
	}

	/** 从缓存获取会员 */
	public JiuWechatMember getMember(Long uid, String openId) {

		JiuWechatMember member = (JiuWechatMember) CacheUtils.get(openId);
		if (member == null) {
			member = jiuWechatMemberService.getByUserIdAndOpenId(uid, openId);
			CacheUtils.put(openId, member);
		}
		return member;
	}
}
